﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using Foundation;
using System.IO;

namespace RPGSoundmixer {
    public class LoadSave {

        private Dictionary<Guid, Effekt> readedEffects = new Dictionary<Guid, Effekt>();


        public CategorieCollection LoadMusicSuite(string path) {
            CategorieCollection collection = CategorieCollection.GetInstance();
            XElement root = XElement.Load(path);
            this.loadCategorie(collection, root);
            
            collection.EffektDictionary = readedEffects; 
            return collection;            
        }

        

        private void loadCategorie(CategorieCollection collection, XElement root) {
            
            foreach (XElement xCategorie in root.Elements("Categorie")) {
                EffektGroup cat = new EffektGroup();
                cat.Key = xCategorie.Attribute("key").Value.ToCharArray()[0];
                cat.Name = xCategorie.Attribute("name").Value;                
                loadEffekt(cat, xCategorie);

                if (collection.Categories.ContainsKey(cat.Key)) {
                    collection.Categories.Remove(cat.Key);
                }
                collection.Categories.Add(cat.Key, cat);
            }

        }

        private void loadEffekt(EffektGroup cat, XElement xCategorie) {
            foreach (XElement xEffekt in xCategorie.Elements("Effekt")) {
                Effekt effect = new Effekt();
                effect.Key = xEffekt.Attribute("key").Value.ToCharArray()[0];
                effect.Name = xEffekt.Attribute("name").Value;
                effect.Type = (EffektTypeEnum)Enum.Parse(typeof(EffektTypeEnum), xEffekt.Attribute("type").Value);
                effect.Id = xEffekt.Attribute("guid") == null ? Guid.NewGuid() : Guid.Parse(xEffekt.Attribute("guid").Value);
                foreach (XElement xTrack in xEffekt.Elements("Track")) {
                    effect.Tracks.Add(new Track(Path.GetFileName(xTrack.Value), Path.GetDirectoryName(xTrack.Value)));
                }                
                if (xEffekt.Attribute("volume") != null) {
                    effect.Volume = Convert.ToInt32(xEffekt.Attribute("volume").Value);
                }
                else {
                    effect.Volume = 255;
                }
                cat.Effects.Add(effect.Key, effect);
                this.readedEffects.Add(effect.Id, effect); 
            }
        }

        public void SaveMusicSuite(CategorieCollection collection, string fileName) {
            XElement root = new XElement("RPGSoundmixerSuite");
            foreach (KeyValuePair<char, EffektGroup> pair in collection.Categories) {
                this.addCategorie(pair.Value, root);
            }
            root.Save(fileName);
        }

        private void addCategorie(EffektGroup categorie, XElement root) {
            XElement xCategorie = new XElement("Categorie");
            xCategorie.SetAttributeValue("key", categorie.Key);
            xCategorie.SetAttributeValue("name", categorie.Name);
            foreach (KeyValuePair<char, Effekt> pair in categorie.Effects) {
                this.addEffekt(pair.Value, xCategorie);
            }
            root.Add(xCategorie); 
        }


        private void addEffekt(Effekt effekt, XElement xCategorie) {
            XElement xEffect = new XElement("Effekt");
            xEffect.SetAttributeValue("guid", effekt.Id);
            xEffect.SetAttributeValue("key", effekt.Key);
            xEffect.SetAttributeValue("name", effekt.Name);
            xEffect.SetAttributeValue("type", Enum.GetName(effekt.Type.GetType(), effekt.Type));
            xEffect.SetAttributeValue("volume", effekt.Volume);
            foreach (Track s in effekt.Tracks) {
                xEffect.Add(new XElement("Track", s.FullPath)); 
            }
            if (effekt.followingEffect != null) {
                xEffect.SetAttributeValue("followingeffect", effekt.followingEffect.Id);
            }
            xCategorie.Add(xEffect);
        }
    }
}
